﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace OnlineFamilyCalendar.Common.Cryptography
{
    public class EncryptionHelper
    {
        string _key = String.Empty;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="key">Base64 encoded key (RijndaelManaged)</param>
        public EncryptionHelper(string key)
        {
            _key = key;
        }

        public static string GenerateKey()
        {
            // Create the algorithm
            var algorithm = new RijndaelManaged();
            algorithm.GenerateKey();

            // Now get the key
            var key = algorithm.Key;
            return Convert.ToBase64String(key); 
        }

        public string EncryptData(string data)
        {
            // Convert string data to byte array
            var clearData = Encoding.UTF8.GetBytes(data);

            // Now Create the algorithm
            var algorithm = new RijndaelManaged();
            algorithm.Key = Convert.FromBase64String(_key); 

            // Encrypt information
            var target = new MemoryStream();

            // Append IV
            algorithm.GenerateIV();
            target.Write(algorithm.IV, 0, algorithm.IV.Length);

            // Encrypt actual data
            var cs = new CryptoStream(target, algorithm.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(clearData, 0, clearData.Length);
            cs.FlushFinalBlock();

            // Output the bytes of the encrypted array
            return Convert.ToBase64String(target.ToArray());
        }

        public string DecryptData(string encryptedValue)
        {
            // convert String to byte[]
            var data = Convert.FromBase64String(encryptedValue);

            // Now Create the algorithm
            var algorithm = new RijndaelManaged();
            algorithm.Key = Convert.FromBase64String(_key); 

            // Decrypt information
            var target = new MemoryStream();

            // Read IV
            var readPos = 0;
            var iv = new byte[algorithm.IV.Length];
            Array.Copy(data, iv, iv.Length);
            algorithm.IV = iv;
            readPos += algorithm.IV.Length;

            var cs = new CryptoStream(target, algorithm.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(data, readPos, data.Length - readPos);
            cs.FlushFinalBlock();

            // Get the bytes from the memory stream and convert them to text
            return Encoding.UTF8.GetString(target.ToArray());
        }
    }
}
